﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.IdentityModel.Claims;
using System.IdentityModel.Policy;
using PSE.Framework.Common.Security.Services.Authentication.ClientCredentials;
using System.Security.Principal;
using PSE.Framework.Service.Security.Authentication;
using System.Net;
using System.ServiceModel;
using System.ServiceModel.Channels;
using PSE.Framework.Service.Security.Identity;
using PSE.Framework.Common.Security.Services.Authentication;

//TODO: Mudar para passar a ser um provider
namespace PSE.Framework.Service.Security.Authentication.ServiceCredentials
{
    class UserNameTokenAuthenticator : SecurityTokenAuthenticator
    {
        protected override bool CanValidateTokenCore(System.IdentityModel.Tokens.SecurityToken token)
        {
            return (token is UserNameSecurityToken);
        }

        /// <summary>
        /// Executa a validação do Token passado.
        /// </summary>
        /// <param name="token">SecurityToken</param>
        /// <returns>Lista de politicas de acesso.</returns>
        protected override System.Collections.ObjectModel.ReadOnlyCollection<System.IdentityModel.Policy.IAuthorizationPolicy> ValidateTokenCore(SecurityToken token)
        {
            ISecurityTokenAuthenticationProvider securityTokenAuthentication = null;

            securityTokenAuthentication = SecurityTokenAutenticationProviderFactory.RetrieveProvider();

            if (!securityTokenAuthentication.ValidateToken(token))
            {
                throw new FaultException(new FaultReason("Invalid token"), new FaultCode("InvalidToken"));
            }

            UserNameSecurityToken userNameToken = token as UserNameSecurityToken;
            
            //criar as claims de authenticacao
            List<Claim> claimList = securityTokenAuthentication.CreateClaims(userNameToken);

            List<IAuthorizationPolicy> policies = new List<IAuthorizationPolicy>();
            policies.Add(new AuthorizationPolicy(new DefaultClaimSet(ClaimSet.System, claimList)));

            return policies.AsReadOnly();


            //UserNameSecurityToken userNameToken = token as UserNameSecurityToken;

            //if (userNameToken != null)
            //{
            //    return HandleUserNameToken(userNameToken);
            //}
            //else
            //    return null;
        }

        ///// <summary>
        ///// Manipula um UserNameToken e retorna a lista de AuthorizationPolicies.
        ///// </summary>
        ///// <param name="token"></param>
        ///// <returns></returns>
        //private System.Collections.ObjectModel.ReadOnlyCollection<IAuthorizationPolicy> HandleUserNameToken(UserNameSecurityToken token)
        //{
        //    List<IAuthorizationPolicy> policies = new List<IAuthorizationPolicy>();

        //    //Cria uma lista com as claims para o usuário.
        //    List<Claim> claimList = CreateClaimList(token.UserName, token.Password);
        //    policies.Add(new AuthorizationPolicy(new DefaultClaimSet(ClaimSet.System, claimList)));

        //    return policies.AsReadOnly();
        //}

        ///// <summary>
        ///// Cria a lista com as Claims do usuário.
        ///// </summary>
        ///// <param name="userId">Id do usuário</param>
        ///// <param name="userName">Login do usuário</param>
        ///// <param name="companyId">Id da empresa</param>
        ///// <returns></returns>
        //private List<Claim> CreateClaimList(string userName, string password)
        //{
        //    List<Claim> result = new List<Claim>();

        //    //Cria uma claim contendo o login do usuário
        //    result.Add(new Claim(CustomClaimTypes.Identity.LoginName, userName, Rights.PossessProperty));
        //    //Cria uma claim contendo o password cifrado do usuário
        //    result.Add(new Claim(CustomClaimTypes.Identity.Password, password, Rights.PossessProperty));

        //    return result;
        //}
    }
}
